/**
 * 
 */
package com.googlecode.pcapj;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Arrays;

/**
 * 
 */
class BinaryData {
	private byte[] buffer;
	private int offset;
	private int length;
	/**
	 * @param buffer
	 * @param offset
	 * @param length
	 */
	BinaryData(byte[] buffer, int offset, int length) {
		super();
		this.buffer = buffer;
		this.offset = offset;
		this.length = length;
	}
	/**
	 * @return the buffer
	 */
	byte[] getBuffer() {
		return buffer;
	}
	/**
	 * @return the offset
	 */
	int getOffset() {
		return offset;
	}
	/**
	 * @return the length
	 */
	int getLength() {
		return length;
	}
	byte[] getBytes(){
		return Arrays.copyOfRange(buffer, offset, offset + length);
	}
	byte[] getBytes(int offset){
		offset += this.offset;
		return Arrays.copyOfRange(buffer, offset, this.offset + length);
	}
	byte[] getBytes(int offset, int length){
		offset += this.offset;
		return Arrays.copyOfRange(buffer, offset, offset + length);
	}
	InetAddress getInetAddress(int offset, int length){
		try {
			return InetAddress.getByAddress(getBytes(offset, length));
		} catch (UnknownHostException e) {
			throw new PcapJRuntimeException(e);
		}
	}
	MACAddress getMACAddress(int offset){
		offset += this.offset;
		return new MACAddressImpl(buffer, offset);
	}
	short getShort(int offset){
		offset += this.offset;
		return (short)(
				(buffer[offset] << 8) | 
				(buffer[offset+1] & 0xff) 
				);
	}
	int getIntFromByte(int offset){
		return 0xff & getByte(offset);
	}
	int getIntFromWord(int offset){
		return 0xffff & getShort(offset);
	}
	int getInt(int offset){
		offset += this.offset;
		return (int)(
				((buffer[offset]   << 24) & 0xff000000) |
				((buffer[offset+1] << 16) & 0xff0000) |
				((buffer[offset+2] <<  8) & 0xff00) |
				((buffer[offset+3]      ) & 0xff) 
				);
	}
	long getLongFromDWord(int offset){
		return 0xffffffffL & (long)getInt(offset);
	}
	byte getByte(int offset){
		offset += this.offset;
		return buffer[offset];
	}
	boolean getBit(int bitOffset){
		int byteOffset = bitOffset / 8;
		int shift = bitOffset % 8;
		int n = getByte(byteOffset);
		return 0 != (n & (0x80 >> shift));
	}
}
